import { Controller, IArticleWhere } from 'egg';
import * as path from 'path'
import * as fs from 'fs'
const fsPromise = require('fs').promises;

export default class ArticlesController extends Controller {
  mysql = this.app.mysql as any;
  public async index() {
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const query = ctx.request.query;
    // let {pagesize, offset, order, reverse, category, author} = query;
    const pagesize = parseInt(query.pagesize);
    const offset = parseInt(query.offset) || 0; // 若无此参数则默认为0
    const reverse:number = parseInt(query.reverse) || 0; // 若无此参数则默认为0
    const { order, category, author } = query;

    // 无正确分页参数
    if (isNaN(pagesize) || isNaN(offset)) {
      ctx.status = 400;
      ctx.body = {
        code: 0,
        message: '分页参数错误',
      };
    } else {
      // 索引
      const where:IArticleWhere = {};
      if (category !== undefined) {
        where.alias = category;
      }
      // 作者
      if (author !== undefined) {
        where.author = author;
      }
      const result = await this.ctx.service.articles.getInfo(pagesize, offset, undefined, where, order, reverse, admin);
      ctx.body = {
        code: 1,
        message: '成功',
        result,
      };
    }
  }
  public async byId() {
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const id = ctx.params.id;
    const query = ctx.request.query;
    // 默认是否文章基本信息，默认包含为0，不包含文章信息
    const hasArticleInfo = !!parseInt(query.hasArticleInfo);
    // 文章信息列名
    const article: any = await this.service.articles.getById(id, hasArticleInfo, admin);
    if (article) {
      // 正常查询到结果
      // 包含的图片名称
      const pictureNames:string[] = []
      try {
        // 读取 ./public/articles/:id 目录下的文件名
        const names = await fsPromise.readdir(path.join(this.config.static.dir,'articles',id)) 
        pictureNames.push(...names);
      } catch (error) {
        
      }
      ctx.body = {
        code: 1,
        message: '成功',
        result: {
          article,
          pictures: pictureNames,
        },
      };
    } else {
      // 没有找到对应的文章
      ctx.status = 404;
      ctx.body = {
        code: 0,
        message: '未找到对应id的文章',
      };
    }
  }
  public async deleteById (){
    
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const id = ctx.params.id;
    if (!admin){
      ctx.status = 401;
      ctx.body = {
        code:1,
        message:"未登录"
      }
      return;
    }
    const result = await ctx.service.articles.deleteById(id);
    if (!result){
      ctx.status = 404
      ctx.body = {
        code:1,
        message:"未找到对应文件"
      }
      return;
    }
    ctx.status = 204;
    ctx.body = {
      code: 0,
      message: "删除成功"
    };
  }
  public async newArticle(){
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const article = ctx.request.body;
    if (!admin){
      ctx.status = 401;
      ctx.body = {
        code:1,
        message:"未登录"
      }
      return;
    }

    const createArticleRule = {
      title: 'string',
      category_id: 'int',
      abstract: 'string',
      content: 'string',
      is_hidden: {
        type: 'number',
        required:false,
      },
      pubdate: {
        type: 'string',
        required: false
      }
    }
    ctx.validate(createArticleRule, ctx.request.body);
    const is_hidden = parseInt(article.is_hidden) ? 1 : 0;
    const insertId = await ctx.service.articles.create(article.title, article.author, article.category_id, article.abstract, article.content, is_hidden ,article.pubdate);
    if (insertId === undefined){
      ctx.status = 400
      ctx.body = {
        code: 1,
        message: "未知错误",
      }
      return
    }

    ctx.body = {
      code: 0,
      message: "成功写入新文章",
      result: {
        article_id: insertId
      }
    }
  }
  public async modify(){
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const {id} = ctx.params;
    const article = ctx.request.body;
    console.log(article);
    if (!admin){
      ctx.status = 401;
      ctx.body = {
        code:1,
        message:"未登录"
      }
      return;
    }

    const updateArticleRule = {
      title: {
        type:'string',
        required:false,
      },
      category_id: {
        type:'int',
        required:false,
      },
      abstract: {
        type:'string',
        required:false,
      },
      content: {
        type:'string',
        required:false,
      },
      is_hidden: {
        type: 'number',
        required:false,
      },
      pubdate: {
        type: 'dateString',
        required: false
      }
    };
    ctx.validate(updateArticleRule, ctx.request.body);
    const is_hidden = parseInt(article.is_hidden) ? 1 : 0;
    let pubdate:string|undefined;
    try {
      pubdate = new Date(Date.parse(article.pubdate)).toISOString();
    } catch (error) {
      pubdate = undefined;
    }
    const message = await ctx.service.articles.updateById(id, article.title, article.author, article.category_id, article.abstract, article.content, is_hidden ,pubdate);
    if (!!message){
      ctx.body = {
        code: 0,
        message: "成功修改",
        result: message
      }
    }

  }
  public async uploadImage(){
    const admin = this.ctx.session.user_id === undefined ? false: true;
    const { ctx } = this;
    const id = parseInt(ctx.params.id);
    const file = ctx.request.files[0];
    // const name = path.basename(file.filename);
    
    if (!admin){
      ctx.status = 401;
      ctx.body = {
        code:1,
        message:"未登录"
      }
      return;
    }
    this.ctx.validate({
      'id': 'int'
    },{id});
    const count = await this.mysql.count('articles',{
      id
    });
    if (count===0) {
      ctx.status = 404;
      ctx.body = {
        code: 1,
        message: "不存在此文章",
      };
      await fsPromise.unlink(file.filepath);
      return;
    }

    // let result;
    try {
      // 处理文件
      const targetDir = path.join(this.config.filePath.articles, id.toString());
      const targetPath = path.join(targetDir,file.filename);
      // 文件夹不存在，则新建文件夹
      if (!fs.existsSync(targetDir)){
        await fsPromise.mkdir(targetDir);
      }
      // 文件重复性判断
      if (fs.existsSync(targetPath)){
        ctx.status = 400;
        ctx.body = {
          code: 1,
          message: "同名文件已存在",
        };
        return;
      }

      await fsPromise.copyFile(file.filepath, targetPath);
      ctx.body = {
        code: 0,
        message: "成功上传图片",
      };
    } catch (error) {
      // bad
      console.error(error);
      
      ctx.status = 500;
      ctx.body = {
        code: 1,
        message: "写入失败",
      };
    } finally {
      await fsPromise.unlink(file.filepath);
    }
  }
}
